<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>watch</title>
    <!-- <script src="../node_modules/vue/dist/vue.global.js"></script> -->
    <script src="./common.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script>
      // --------------- 源码的实现部分 --------------------
      const traverse = (value, seen = new Set()) => {
        if (!isObject(value)) return value

        if (seen.has(value)) return value
        seen.add(value)

        for (const key in value) {
          traverse(value[key], seen)
        }

        return value
      }

      const doWatch = (source, cb, { deep, immediate } = options) => {
        let getter

        if (isReactive(source)) {
          getter = () => source
          deep = true
        }

        // 如果是对象 递归遍历
        if (cb && deep) {
          const baseGetter = getter
          getter = () => traverse(baseGetter())
        }

        let effect
        let oldValue
        const job = () => {
          if (!effect.active) return

          if (cb) {
            const newValue = effect.run()
            cb(oldValue, newValue)
          }
        }

        effect = new ReactiveEffect(getter, job)
        if (immediate) {
          job()
        } else {
          oldValue = effect.run()
        }
      }

      const watch = (source, cb, options = {}) => {
        return doWatch(source, cb, options)
      }

      // ------------- 代码的测试部分------------------------
      const { reactive, effect } = Vue1
      const state = reactive({ name: 'lihh', age: 20 })

      watch(state, (newValue, oldValue) => {
        console.log(newValue, oldValue)
      })

      setTimeout(() => {
        state.age++
      }, 3000)

      effect(() => {
        document.getElementById('app').innerHTML = `我叫${state.name}, 今年${state.age}岁, ${
          status.value ? '我是学生' : '我不是学生'
        }`
      })
    </script>
  </body>
</html>
